package com.mjf.cjt.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chanjet.openapi.sdk.java.exception.ChanjetApiException;
import com.mjf.cjt.domain.TCjtExpensevoucher;
import com.mjf.cjt.domain.TCjtExpensevoucherDetails;
import com.mjf.cjt.domain.TCjtSaleOrderDetails;
import com.mjf.cjt.domain.TCjtSaleOrderVo;
import com.mjf.cjt.mapper.TCjtExpensevoucherMapper;
import com.mjf.cjt.service.AsyncTMService;
import com.mjf.cjt.service.TCjtExpensevoucherDetailsService;
import com.mjf.cjt.service.TCjtExpensevoucherService;
import com.mjf.cjt.vo.*;
import com.mjf.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 销售订单列表查询
 * </p>
 *
 * @author
 * @since 2025-04-05
 */
@Service
public class TCjtExpensevoucherServiceImpl extends ServiceImpl<TCjtExpensevoucherMapper, TCjtExpensevoucher> implements TCjtExpensevoucherService {
    @Autowired
    private AsyncTMService asyncTMService;

    @Autowired
    private TCjtExpensevoucherDetailsService tcjtExpensevoucherDetailsService;

    @Override
    public Page<TCjtExpensevoucherListVo> queryTCjtExpensevoucher(TCjtExpensevoucherQueryParam param) {

        Page<TCjtExpensevoucherListVo> page = new Page<>(param.getPage(), param.getSize());
        page.setTotal(0);
        page.setRecords(new ArrayList<>());
        LambdaQueryWrapper<TCjtExpensevoucher> qw = Wrappers.<TCjtExpensevoucher>lambdaQuery()
                .ge(StrUtil.isNotBlank(param.getStart()), TCjtExpensevoucher::getCreatedTime, param.getStart())
                .le(StrUtil.isNotBlank(param.getEnd()), TCjtExpensevoucher::getCreatedTime, param.getEnd())
                ;
        long count = count(qw);
        page.setTotal(count);
        qw.orderByDesc(TCjtExpensevoucher::getCreatedTime);
        qw.last("limit " + (param.getPage() - 1) * param.getSize() + "," + param.getSize());

        List<TCjtExpensevoucher> list = list(qw);
        page.setRecords(list.stream().map(item -> TCjtExpensevoucherListVo.builder()
                        .expenseVoucherId(item.getExpenseVoucherId())
                        .businessTypeName(item.getBusinessTypeName())
                        .code(item.getCode())
                        .voucherdate(item.getVoucherdate())
                        .billtypeName(item.getBilltypeName())
                        .invoiceCode(item.getInvoiceCode())
                        .partnerCode(item.getPartnerCode())
                        .partnerName(item.getPartnerName())
                        .partnerAbbname(item.getPartnerAbbname())
                        .arapAccountDirectionName(item.getArapAccountDirectionName())
                        .partnerPriuserdefnvc1(item.getPartnerPriuserdefnvc1())
                        .partnerPriuserdefnvc2(item.getPartnerPriuserdefnvc2())
                        .partnerPriuserdefnvc3(item.getPartnerPriuserdefnvc3())
                        .partnerPriuserdefnvc4(item.getPartnerPriuserdefnvc4())
                        .partnerPriuserdefnvc5(item.getPartnerPriuserdefnvc5())
                        .partnerPriuserdefdecm1(item.getPartnerPriuserdefdecm1())
                        .partnerPriuserdefdecm2(item.getPartnerPriuserdefdecm2())
                        .partnerPriuserdefdecm3(item.getPartnerPriuserdefdecm3())
                        .partnerPriuserdefdecm4(item.getPartnerPriuserdefdecm4())
                        .partnerPriuserdefdecm5(item.getPartnerPriuserdefdecm5())
                        .deptName(item.getDeptName())
                        .storeName(item.getStoreName())
                        .clerkName(item.getClerkName())
                        .settlestyleName(item.getSettlestyleName())
                        .bankAccountName(item.getBankAccountName())
                        .currencyName(item.getCurrencyName())
                        .exchangeRate(item.getExchangeRate())
                        .arrivalDate(item.getArrivalDate())
                        .sourceVouchertypeName(item.getSourceVouchertypeName())
                        .sourceVoucherCode(item.getSourceVoucherCode())
                        .saleOrderCode(item.getSaleOrderCode())
                        .purchaseOrderCode(item.getPurchaseOrderCode())
                        .memo(item.getMemo())
                        .maker(item.getMaker())
                        .agency(item.getAgency())
                        .reviser(item.getReviser())
                        .auditor(item.getAuditor())
                        .auditedDate(item.getAuditedDate())
                        .auditedTime(item.getAuditedTime())
                        .printcount(item.getPrintcount())
                        .changer(item.getChanger())
                        .changeDate(item.getChangeDate())
                        .origTaxamountSum(item.getOrigTaxamountSum())
                        .taxamountSum(item.getTaxamountSum())
                        .origAmount(item.getOrigAmount())
                        .amount(item.getAmount())
                        .origPaymentAmount(item.getOrigPaymentAmount())
                        .paymentAmount(item.getPaymentAmount())
                        .voucherstateName(item.getVoucherstateName())
                        .docId(item.getDocId())
                        .vouchersettlestateName(item.getVouchersettlestateName())
                        .priuserdefnvc1(item.getPriuserdefnvc1())
                        .priuserdefnvc2(item.getPriuserdefnvc2())
                        .priuserdefnvc3(item.getPriuserdefnvc3())
                        .priuserdefnvc4(item.getPriuserdefnvc4())
                        .priuserdefnvc5(item.getPriuserdefnvc5())
                        .priuserdefnvc6(item.getPriuserdefnvc6())
                        .priuserdefdecm1(item.getPriuserdefdecm1())
                        .priuserdefdecm2(item.getPriuserdefdecm2())
                        .priuserdefdecm3(item.getPriuserdefdecm3())
                        .priuserdefdecm4(item.getPriuserdefdecm4())
                        .priuserdefdecm5(item.getPriuserdefdecm5())
                        .priuserdefdecm6(item.getPriuserdefdecm6())
                        .pubuserdefnvc1(item.getPubuserdefnvc1())
                        .pubuserdefnvc2(item.getPubuserdefnvc2())
                        .pubuserdefnvc3(item.getPubuserdefnvc3())
                        .pubuserdefnvc4(item.getPubuserdefnvc4())
                        .pubuserdefnvc5(item.getPubuserdefnvc5())
                        .pubuserdefnvc6(item.getPubuserdefnvc6())
                        .pubuserdefdecm1(item.getPubuserdefdecm1())
                        .pubuserdefdecm2(item.getPubuserdefdecm2())
                        .pubuserdefdecm3(item.getPubuserdefdecm3())
                        .pubuserdefdecm4(item.getPubuserdefdecm4())
                        .pubuserdefdecm5(item.getPubuserdefdecm5())
                        .pubuserdefdecm6(item.getPubuserdefdecm6())
                        .ts(item.getTs())
                        .createdTime(item.getCreatedTime())
                        .busopAttachCount(item.getBusopAttachCount())
                        .datasourceVoucherCode(item.getDatasourceVoucherCode())
                        .marketingOrganName(item.getMarketingOrganName())
                        .datasourceCode(item.getDatasourceCode())
                        .build())
                .collect(Collectors.toList()));
        return page;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void getExpensevoucherFromRemote(String start, String end) {
        try {
            List<ExpensevoucherVo> saleOrderRemote = asyncTMService.getExpensevoucherFromRemote(start, end);
            if (CollectionUtil.isNotEmpty(saleOrderRemote)) {
                // 按明细行ID分组
                Map<Long, List<ExpensevoucherVo>> voMap =
                        saleOrderRemote.stream().collect(Collectors.groupingBy(ExpensevoucherVo::getId));

                List<TCjtExpensevoucher> tcjtExpensevoucher = new ArrayList<>();

                List<TCjtExpensevoucherDetails> tcjtExpensevoucherDetails = new ArrayList<>();

                for (Map.Entry<Long, List<ExpensevoucherVo>> entry : voMap.entrySet()) {

                    // 主单
                    TCjtExpensevoucher order = new TCjtExpensevoucher();
                    order.setExpenseVoucherId(entry.getValue().get(0).getId());
                    order.setBusinessTypeName(entry.getValue().get(0).getBusinesstype_name());
                    order.setCode(entry.getValue().get(0).getCode());
                    order.setVoucherdate(entry.getValue().get(0).getVoucherdate());
                    order.setBilltypeName(entry.getValue().get(0).getBilltype_name());
                    order.setInvoiceCode(entry.getValue().get(0).getInvoicecode());
                    order.setPartnerCode(entry.getValue().get(0).getPartner_code());
                    order.setPartnerName(entry.getValue().get(0).getPartner_name());
                    order.setPartnerAbbname(entry.getValue().get(0).getPartner_partnerabbname());
                    order.setArapAccountDirectionName(entry.getValue().get(0).getArapaccountdirection_name());
                    order.setPartnerPriuserdefnvc1(entry.getValue().get(0).getPartner_priuserdefnvc1());
                    order.setPartnerPriuserdefnvc2(entry.getValue().get(0).getPartner_priuserdefnvc2());
                    order.setPartnerPriuserdefnvc3(entry.getValue().get(0).getPartner_priuserdefnvc3());
                    order.setPartnerPriuserdefnvc4(entry.getValue().get(0).getPartner_priuserdefnvc4());
                    order.setPartnerPriuserdefnvc5(entry.getValue().get(0).getPartner_priuserdefnvc5());
                    order.setPartnerPriuserdefdecm1(entry.getValue().get(0).getPartner_priuserdefdecm1());
                    order.setPartnerPriuserdefdecm2(entry.getValue().get(0).getPartner_priuserdefdecm2());
                    order.setPartnerPriuserdefdecm3(entry.getValue().get(0).getPartner_priuserdefdecm3());
                    order.setPartnerPriuserdefdecm4(entry.getValue().get(0).getPartner_priuserdefdecm4());
                    order.setPartnerPriuserdefdecm5(entry.getValue().get(0).getPartner_priuserdefdecm5());
                    order.setDeptName(entry.getValue().get(0).getDepartment_name());
                    order.setStoreName(entry.getValue().get(0).getStore_name());
                    order.setClerkName(entry.getValue().get(0).getClerk_name());
                    order.setSettlestyleName(entry.getValue().get(0).getSettlestyle_name());
                    order.setBankAccountName(entry.getValue().get(0).getBankaccount_name());
                    order.setCurrencyName(entry.getValue().get(0).getCurrency_name());
                    order.setArrivalDate(entry.getValue().get(0).getArrivaldate());
                    order.setSourceVouchertypeName(entry.getValue().get(0).getSourcevouchertype_name());
                    order.setSourceVoucherCode(entry.getValue().get(0).getSourcevouchercode());
                    order.setSaleOrderCode(entry.getValue().get(0).getSaleordercode());
                    order.setPurchaseOrderCode(entry.getValue().get(0).getPurchaseordercode());
                    order.setMemo(entry.getValue().get(0).getMemo());
                    order.setMaker(entry.getValue().get(0).getMaker());
                    order.setAgency(entry.getValue().get(0).getAgency());
                    order.setReviser(entry.getValue().get(0).getReviser());
                    order.setAuditor(entry.getValue().get(0).getAuditor());
                    order.setAuditedDate(entry.getValue().get(0).getAuditeddate());
                    order.setAuditedTime(entry.getValue().get(0).getAuditedtime());
                    order.setPrintcount(entry.getValue().get(0).getPrintcount());
                    order.setOrigTaxamountSum(entry.getValue().get(0).getOrigtaxamountsum());
                    order.setTaxamountSum(entry.getValue().get(0).getTaxamountsum());
                    order.setOrigAmount(entry.getValue().get(0).getOrigamount());
                    order.setAmount(entry.getValue().get(0).getAmount());
                    order.setOrigPaymentAmount(entry.getValue().get(0).getOrigpaymentamount());
                    order.setPaymentAmount(entry.getValue().get(0).getPaymentamount());
                    order.setVoucherstateName(entry.getValue().get(0).getVoucherstate_name());
                    order.setDocId(entry.getValue().get(0).getDocid());
                    order.setVouchersettlestateName(entry.getValue().get(0).getVouchersettlestate_name());
                    order.setPriuserdefnvc1(entry.getValue().get(0).getPriuserdefnvc1());
                    order.setPriuserdefnvc2(entry.getValue().get(0).getPriuserdefnvc2());
                    order.setPriuserdefnvc3(entry.getValue().get(0).getPriuserdefnvc3());

                    order.setPriuserdefnvc4(entry.getValue().get(0).getPriuserdefnvc4());
                    order.setPriuserdefnvc5(entry.getValue().get(0).getPriuserdefnvc5());
                    order.setPriuserdefnvc6(entry.getValue().get(0).getPriuserdefnvc6());
                    order.setPriuserdefdecm1(entry.getValue().get(0).getPriuserdefdecm1());
                    order.setPriuserdefdecm2(entry.getValue().get(0).getPriuserdefdecm2());
                    order.setPriuserdefdecm3(entry.getValue().get(0).getPriuserdefdecm3());
                    order.setPriuserdefdecm4(entry.getValue().get(0).getPriuserdefdecm4());
                    order.setPriuserdefdecm5(entry.getValue().get(0).getPriuserdefdecm5());
                    order.setPriuserdefdecm6(entry.getValue().get(0).getPriuserdefdecm6());
                    order.setPubuserdefnvc1(entry.getValue().get(0).getPubuserdefnvc1());
                    order.setPubuserdefnvc2(entry.getValue().get(0).getPubuserdefnvc2());
                    order.setPubuserdefnvc3(entry.getValue().get(0).getPubuserdefnvc3());
                    order.setPubuserdefnvc4(entry.getValue().get(0).getPubuserdefnvc4());
                    order.setPubuserdefnvc5(entry.getValue().get(0).getPubuserdefnvc5());
                    order.setPubuserdefnvc6(entry.getValue().get(0).getPubuserdefnvc6());
                    order.setPubuserdefdecm1(entry.getValue().get(0).getPubuserdefdecm1());
                    order.setPubuserdefdecm2(entry.getValue().get(0).getPubuserdefdecm2());
                    order.setPubuserdefdecm3(entry.getValue().get(0).getPubuserdefdecm3());
                    order.setPubuserdefdecm4(entry.getValue().get(0).getPubuserdefdecm4());
                    order.setPubuserdefdecm5(entry.getValue().get(0).getPubuserdefdecm5());
                    order.setPubuserdefdecm6(entry.getValue().get(0).getPubuserdefdecm6());
                    order.setTs(entry.getValue().get(0).getTs());
                    order.setCreatedTime(entry.getValue().get(0).getCreatedtime());
                    order.setBusopAttachCount(entry.getValue().get(0).getBusopattachcount());
                    order.setDatasourceVoucherCode(entry.getValue().get(0).getDatasourcevouchercode());
                    order.setMarketingOrganName(entry.getValue().get(0).getMarketingorgan_name());
                    order.setDatasourceCode(entry.getValue().get(0).getDatasourcecode());

                    tcjtExpensevoucher.add(order);

                    // 按明细ID分组
                    Map<Long, List<ExpensevoucherVo>> detailsMap = entry.getValue().stream().collect(Collectors.groupingBy(ExpensevoucherVo::getPartner_id));
                    for (Map.Entry<Long, List<ExpensevoucherVo>> detailsEntry : detailsMap.entrySet()) {
                        // 明细
                        ExpensevoucherVo orderDetail = detailsEntry.getValue().get(0);
                        TCjtExpensevoucherDetails details = new TCjtExpensevoucherDetails();
                        details.setExpenseitemId(orderDetail.getPartner_id());
                        details.setExpenseId(orderDetail.getId());
                        details.setName(orderDetail.getExpenseitem_name());
                        details.setCode(orderDetail.getExpenseitem_code());
                        details.setTaxrate(orderDetail.getTaxrate());
                        details.setOrigAmount(orderDetail.getOrigamount());
                        details.setInventoryclassName(orderDetail.getDetails_inventoryclass_name());
                        details.setCorpbrandName(orderDetail.getDetails_corpbrand_name());
                        details.setInventoryName(orderDetail.getDetails_inventory_name());
                        details.setApportionInputNum(Objects.isNull(orderDetail.getApportioninputnum())? null : new BigDecimal(orderDetail.getApportioninputnum()));
                        details.setApportionNum(Objects.isNull(orderDetail.getApportionnum())? null : new BigDecimal(orderDetail.getApportionnum()));
                        details.setOrigtax(orderDetail.getOrigtax());
                        details.setOrigtaxAmount(orderDetail.getOrigtaxamount());
                        details.setAmount(orderDetail.getAmount());
                        details.setTax(orderDetail.getTax());
                        details.setTaxAmount(orderDetail.getTaxamount());
                        details.setDeductAmount(orderDetail.getDeductamount());
                        details.setOrigSettleAmount(orderDetail.getOrigsettleamount());
                        details.setIsdeduct(orderDetail.getIsdeduct());
                        details.setDeductRate(orderDetail.getDeductrate());
                        details.setOrigDeductAmount(orderDetail.getOrigdeductamount());
                        details.setExpenseitemuse(orderDetail.getExpenseitemuse());
                        details.setIsapportion(orderDetail.getIsapportion());
                        details.setPriuserdefnvc1(orderDetail.getPriuserdefnvc1());
                        details.setPriuserdefnvc2(orderDetail.getPriuserdefnvc2());
                        details.setPriuserdefnvc3(orderDetail.getPriuserdefnvc3());
                        details.setPriuserdefnvc4(orderDetail.getPriuserdefnvc4());
                        details.setPriuserdefdecm1(orderDetail.getPriuserdefdecm1());
                        details.setPriuserdefdecm2(orderDetail.getPriuserdefdecm2());
                        details.setPriuserdefdecm3(orderDetail.getPriuserdefdecm3());
                        details.setPriuserdefdecm4(orderDetail.getPriuserdefdecm4());
                        details.setPubuserdefnvc1(orderDetail.getPubuserdefnvc1());
                        details.setPubuserdefnvc2(orderDetail.getPubuserdefnvc2());
                        details.setPubuserdefnvc3(orderDetail.getPubuserdefnvc3());
                        details.setPubuserdefnvc4(orderDetail.getPubuserdefnvc4());
                        details.setPubuserdefdecm1(orderDetail.getPubuserdefdecm1());
                        details.setPubuserdefdecm2(orderDetail.getPubuserdefdecm2());
                        details.setPubuserdefdecm3(orderDetail.getPubuserdefdecm3());
                        details.setPubuserdefdecm4(orderDetail.getPubuserdefdecm4());
                        tcjtExpensevoucherDetails.add(details);

                    }
                }
                saveOrUpdateBatch(tcjtExpensevoucher);
                tcjtExpensevoucherDetailsService.saveOrUpdateBatch(tcjtExpensevoucherDetails);
            }
        } catch (ChanjetApiException e) {
            throw new RuntimeException(e);
        }

    }

}
